package com.wsoft.sms.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsoft.constant.redis.RedisKeyConstant;
import com.wsoft.constant.redis.sms.SmsRedisConstant;
import com.wsoft.core.service.RedisService;
import com.wsoft.sms.entity.SmsMessageReadEntity;
import com.wsoft.sms.mapper.SmsMessageReadMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author Zhang gukai
 * @Date 2025/1/7 10:35
 */

@Slf4j
@Service
public class MessageReadManager extends ServiceImpl<SmsMessageReadMapper, SmsMessageReadEntity> {

    @Resource
    private RedisService redisService;

    public Set<Long> getByMemberId(Long memberId){
        Set<Object> set = redisService.sMembers(SmsRedisConstant.SMS_MESSAGE_READ_MEMBER_LIST + memberId);
        if(CollUtil.isNotEmpty(set)){
            return  set.stream().map(item-> Long.valueOf(item.toString())).collect(Collectors.toSet());
        }

        QueryWrapper<SmsMessageReadEntity> query = new QueryWrapper<>();
        query.lambda().eq(SmsMessageReadEntity::getMemberId, memberId);
        List<SmsMessageReadEntity> list = list(query);
        if(CollUtil.isEmpty(list)){
            return new HashSet<>();
        }else{
            Set<Long> collect = list.stream().map(SmsMessageReadEntity::getMessageId).collect(Collectors.toSet());
            for (Long l : collect) {
                redisService.sAdd(SmsRedisConstant.SMS_MESSAGE_READ_MEMBER_LIST + memberId,l);
            }
            return collect;
        }
    }
    /**
     * 批量保存
     * @param memberId
     * @param readList
     * @return boolean
     */
    public boolean saveBatch(Long memberId,List<SmsMessageReadEntity> readList){
        boolean b = super.saveBatch(readList);
        if(b){
            for (SmsMessageReadEntity read : readList) {
                redisService.sAdd(SmsRedisConstant.SMS_MESSAGE_READ_MEMBER_LIST + memberId,read.getMessageId());
            }
        }
        return b;
    }

    /**
     * 记录 阅读记录
     *
     * @param messageId
     * @param memberId
     * @return
     */
    public void read(Long messageId, Long memberId) {
        Boolean b = redisService.sIsMember(SmsRedisConstant.SMS_MESSAGE_READ_LIST + messageId, memberId);
        if (!b) {
            SmsMessageReadEntity info = getInfo(messageId, memberId);
            if(null == info){
                SmsMessageReadEntity read = new SmsMessageReadEntity();
                read.setMessageId(messageId);
                read.setMemberId(memberId);
                read.setReadTime(LocalDateTime.now());
                read.setReadFlag(1);
                save(read);
                redisService.set(SmsRedisConstant.SMS_MESSAGE_READ_INFO + messageId + StrUtil.COLON + memberId, read);
            }
            redisService.sAdd(SmsRedisConstant.SMS_MESSAGE_READ_LIST + messageId, memberId);
            //防止缓存删除后,只保存当前记录,导致后续问题
            getByMemberId(memberId);
            redisService.sAdd(SmsRedisConstant.SMS_MESSAGE_READ_MEMBER_LIST + memberId, messageId);
        }
    }

    /**
     * 查询数据库 获取信息
     * @param messageId
     * @param memberId
     * @return
     */
    public SmsMessageReadEntity getInfo(Long messageId, Long memberId) {
        Object object = redisService.get(SmsRedisConstant.SMS_MESSAGE_READ_INFO + messageId + StrUtil.COLON + memberId);
        if(ObjUtil.isNotEmpty(object)){
            return (SmsMessageReadEntity)object;
        }

        QueryWrapper<SmsMessageReadEntity> query = new QueryWrapper<>();
        query.lambda().eq(SmsMessageReadEntity::getMessageId, messageId)
                .eq(SmsMessageReadEntity::getMemberId, memberId);
        SmsMessageReadEntity readEntity = getOne(query);
        if(null != readEntity){
            redisService.set(SmsRedisConstant.SMS_MESSAGE_READ_INFO + messageId + StrUtil.COLON + memberId, readEntity);
        }
        return readEntity;
    }

}
